package com.fooddiary.dao.impl;

import java.util.Collection;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;

import com.fooddiary.dao.IBaseDao;
import com.fooddiary.model.entity.BaseEntity;
import com.fooddiary.util.AppConstants;

/**
 * Implements common DAO methods
 * @author Andrey
 */
@Repository
public class BaseDao implements IBaseDao{

	protected final Log log = LogFactory.getLog(this.getClass());
	
	protected final String PROPERTY_ID = "id";
	protected final String PROPERTY_ENABLED = "enabled";
	

	protected HibernateTemplate hibernateTemplate;

	@Autowired
	public void setSessionFactory(SessionFactory sessionFactory) {
		hibernateTemplate = new HibernateTemplate(sessionFactory);
	}

	@SuppressWarnings("rawtypes")
	public Object saveOrUpdate(Object p_obj) {
		Class cl=p_obj.getClass();
		p_obj=cl.cast(p_obj);
		hibernateTemplate.saveOrUpdate(p_obj);
		return p_obj;
	}
	
	@Override
	public <T> void saveOrUpdateAll(Collection<T> p_obj) {
		hibernateTemplate.saveOrUpdateAll( p_obj );
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public List<BaseEntity> getEnabledEntitiesByIds(Class p_class, List<Integer> p_Ids) {
		DetachedCriteria criteria = DetachedCriteria.forClass(p_class)
		.add(Restrictions.in(PROPERTY_ID, p_Ids))
		.add(Restrictions.eq(PROPERTY_ENABLED, AppConstants.ENTITY_STATE_ENABLED));
		
		return hibernateTemplate.findByCriteria(criteria);
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public BaseEntity getById(Class p_class, Integer p_Id) {
		DetachedCriteria criteria = DetachedCriteria.forClass(p_class)
		.add(Restrictions.eq(PROPERTY_ID, p_Id))
		.add(Restrictions.eq(PROPERTY_ENABLED, AppConstants.ENTITY_STATE_ENABLED));
		
		List<BaseEntity> entities = hibernateTemplate.findByCriteria(criteria);
		return CollectionUtils.isNotEmpty(entities) ? entities.get(0) : null;
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public <T> List<T> getEnabledEntities(Class p_class) {
		DetachedCriteria criteria = DetachedCriteria.forClass(p_class)
		.add(Restrictions.eq(PROPERTY_ENABLED, AppConstants.ENTITY_STATE_ENABLED));
		criteria.addOrder(Order.asc(PROPERTY_ID));
		return hibernateTemplate.findByCriteria(criteria);
	}
	
}
